package org.putrpctorest.resource.impl;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.putrpctorest.resource.Resource;
import org.putrpctorest.resource.Verb;

public class ResourceImpl implements Resource {
	
	private String id;
	private String description;
	private String pathPart;
	private String path;
	private Set<String> produces = new HashSet<String>();
	private Set<String> consumes = new HashSet<String>();
	private Set<MethodImpl> methods = new HashSet<MethodImpl>();
    private Class<?> returnEntity;
    private Set<ResourceImpl> resources = new HashSet<ResourceImpl>();
    private Resource parent;
	
    @Override
    public String getId() {
        return id;
    }

    public void setId(String id) {
		this.id = id;
	}
    
    @Override
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
    
    @Override
    public String getPathPart() {
        return pathPart;
    }
    
    public void setPathPart(String pathPart) {
        this.pathPart = pathPart;
    }

	public void setPath(String path) {
		this.path = path;
	}
	
	@Override
	public String getPath() {
		return path;
	}
	
	public void setProduces(Set<String> mediaTypes) {
		produces = new HashSet<String>(mediaTypes);
	}
	
	@Override
	public Set<String> getProduces() {
		Set<String> allProduces = new HashSet<String>();
		allProduces.addAll(produces);
		allProduces.addAll(getParent().getProduces());
		return Collections.unmodifiableSet(allProduces);
	}
	
	public void addProduces(String mediaType) {
		produces.add(mediaType);
	}
	
	public void setConsumes(Set<String> mediaTypes) {
		consumes = new HashSet<String>(mediaTypes);
	}
	
	@Override
	public Set<String> getConsumes() {
		Set<String> allConsumes = new HashSet<String>();
		allConsumes.addAll(consumes);
		allConsumes.addAll(getParent().getConsumes());
		return Collections.unmodifiableSet(allConsumes);
	}
	
	public  void addConsumes(String mediaType) {
		consumes.add(mediaType);
	}
	
	public void setMethods(Set<MethodImpl> methods) {
		this.methods = new HashSet<MethodImpl>();
		for(MethodImpl method:methods) {
			addMethod(method);
		}
	}
	
	@Override
	public Set<MethodImpl> getMethods() {
		return Collections.unmodifiableSet(methods);
	}
	
	@Override
	public MethodImpl getMethod(Verb verb) {
		for(MethodImpl method:getMethods()) {
			if (method.getVerb() == verb) {
				return method;
			}
		}
		return null;
	}
	
	public void addMethod(MethodImpl method) {
		if (method.getResource() == null) {
		  method.setResource(this);
		}
		methods.add(method);
	}
	
	public Class<?> getReturnEntity() {
	    return returnEntity;
	}
	
	public void setReturnEntity(Class<?> returnEntity) {
	    this.returnEntity = returnEntity;
	}

    @Override
    public Set<? extends Resource> getResources() {
        return Collections.unmodifiableSet(resources);
    }

    @Override
    public Resource getParent() {
        return parent;
    }
    
    public void setParent(Resource parent) {
        this.parent = parent;
    }

	

}
